package com.web.portal.util;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.web.portal.dao.BaseDao;

public abstract class WebportalHibernateDaoSupport<T, PK extends Serializable>
		extends HibernateDaoSupport implements BaseDao<T, PK>

{
	private static final Logger LOG = Logger
			.getLogger(WebportalHibernateDaoSupport.class);
	private Class<? extends T> type;

	public WebportalHibernateDaoSupport() {
		super();
		// TODO Auto-generated constructor stub
		Type thisType = getClass().getGenericSuperclass();
		while (thisType instanceof Class) {
			thisType = ((Class<?>) thisType).getGenericSuperclass();
		}
		if (thisType instanceof ParameterizedType) {
		} else {
			throw new IllegalArgumentException(
					"Problem handling type construction for " + getClass());
		}

	}

	protected WebportalHibernateDaoSupport(final Class<? extends T> type) {
		super();
		this.type = type;
	}

	/*
	 * @Autowired public void anyMethodName(SessionFactory sessionFactory) {
	 * setSessionFactory(sessionFactory); }
	 */

	public void saveOrUpdate(final T transienIinstance) {
		LOG.debug("Persisting the object.......................");
		/*
		 * check for empty entity
		 */
		if (!(transienIinstance == null)) {
			try {

				getSession().saveOrUpdate(transienIinstance);
				LOG.debug("persistence successfull........................");

			} catch (HibernateException e) {

				e.printStackTrace();
				LOG.debug("Unable to persist: failure " + e);
			} catch (RuntimeException e) {
				LOG.debug("Errors on persisting....");
			}
		} else {
			LOG.debug("Given entity has null values hence cannot be persisted!");
			try {
				throw new Exception(
						"The given entity has null value and cannot be persisted");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	protected abstract void populateCriteria(
			final Map<? extends Enum<?>, Object> searchCriteria,
			final Criteria criteria);

	public List<T> search(Map<? extends Enum<?>, Object> searchCriteria,
			Class<? extends T> searchType) {
		/*
		 * default to base type
		 */
		Class<? extends T> typeToSearch = searchType;
		if (typeToSearch == null) {
			typeToSearch = type;
		}
		try {
			final Criteria criteria = getSession().createCriteria(typeToSearch);
			populateCriteria(searchCriteria, criteria);

			@SuppressWarnings("unchecked")
			List<T> result = (List<T>) criteria.list();
			if (result == null) {
				LOG.debug("Empty result found");
				result = Collections.emptyList();
			}
			/*
			 * returning list from Criteria query
			 */
			return result;
		} catch (RuntimeException e) {
			LOG.debug("unable to populate query " + e);
			throw e;
		}

	}

	public void delete(T instance) {
		// TODO Auto-generated method stub
LOG.debug("calling session factory to delete the record.................");
if (!(instance == null)) {
	try {

		getSession().delete(instance);
		LOG.debug("Deletion successfull........................");

	} catch (HibernateException e) {

		e.printStackTrace();
		LOG.debug("Unable to persist: failure " + e);
	} catch (RuntimeException e) {
		LOG.debug("Errors on persisting....");
	}
} else {
	LOG.debug("Given entity is null hence cannot be Deleted!");
	try {
		throw new Exception(
				"The given entity is null value and cannot be deleted");
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
	}

	/*
	 * public abstract List<T> listItems(final T instance); { // TODO
	 * Auto-generated method stub
	 * 
	 * try {
	 * 
	 * LOG.debug("Querying items from the list..........................");
	 * 
	 * @SuppressWarnings("unchecked") List<T> result = (List<T>)
	 * getSession().createQuery( "from instance").list(); if (result == null) {
	 * LOG.debug("Empty result found"); result = Collections.emptyList(); }
	 * 
	 * 
	 * LOG.debug(
	 * "Querying items is successfully executed...........................");
	 * LOG.debug("Returning result..............."); return result; } catch
	 * (RuntimeException e) { LOG.debug("unable to populate query " + e); throw
	 * e; } }
	 */

}
